package cn.iotab.iotkit.transport.mqtt.handler;

import cn.iotab.iotkit.transport.api.common.message.msg.CommonPayload;
import cn.iotab.iotkit.transport.api.common.message.msg.down.CloseSessionCmd;
import cn.iotab.iotkit.transport.api.driver.SessionMsgListener;
import cn.iotab.iotkit.transport.mqtt.session.MqttSessionCtx;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SessionMsgHandler implements SessionMsgListener {

    private final String sessionId;
    private final MqttSessionCtx deviceSessionCtx;

    public SessionMsgHandler(MqttSessionCtx deviceSessionCtx) {
        this.sessionId = deviceSessionCtx.getSessionId();
        this.deviceSessionCtx = deviceSessionCtx;
    }

    @Override
    public void onRemoteSessionCloseCommand(CloseSessionCmd closeSessionCmd) {
        log.info("[{}] Received the remote command to close the session", sessionId);
        deviceSessionCtx.processDisconnect();
    }

    @Override
    public void onToDeviceRequest(CommonPayload toDeviceRequest) {
        log.trace("[{}] Received ToDeviceRequest to device", sessionId);
        try {
            deviceSessionCtx.getPayloadAdaptor().convertToDeviceRequest(deviceSessionCtx, toDeviceRequest).ifPresent(deviceSessionCtx.getChannelHandlerContext()::writeAndFlush);
        } catch (Exception e) {
            log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e);
        }
    }

    @Override
    public void onToDeviceResponse(CommonPayload toDeviceResponse) {
        log.trace("[{}] Received ToDeviceResponse to device", sessionId);
        try {
            deviceSessionCtx.getPayloadAdaptor().convertToDeviceResponse(deviceSessionCtx, toDeviceResponse).ifPresent(deviceSessionCtx.getChannelHandlerContext()::writeAndFlush);
        } catch (Exception e) {
            log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e);
        }
    }
}
